import { defineStore } from 'pinia';
import { getToken, removeToken, setToken } from '../utils/token-utils';
import type { UserInfoState } from './interface';
import {allAsyncRoutes, anyRouter, staticRoutes} from '@/router/routes'
import { getUserInfoApi, loginApi, logoutApi } from '@/api/acl/login';
import type { RouteRecordRaw } from 'vue-router';
import router from '@/router';
import {cloneDeep} from 'lodash'

/* 对所有的异步路由进行过滤得到用户权限路由表 */
function filterAsyncRoutes(allAsyncRoutes :RouteRecordRaw[],routeNames:string[]): RouteRecordRaw[]{
   // 如果route的name没有在routeNames中, 过滤它(返回false)
  return allAsyncRoutes.filter(route=>{
    if(!routeNames.includes(route.name as string)) return false
    // 如果当前route有子路由, 需要子路由进行递归过滤
    if(route.children && route.children.length>0){
     route.children = filterAsyncRoutes(route.children,routeNames)//一定要对children进行重新赋值
    }
    // 否则返回true
    return true
  })
}
//  注册指定的路由表
function addRoutes(routes:RouteRecordRaw[]){
  routes.forEach(route => router.addRoute(route))
}

// 
function resetRoute(){
  // 得到所有已经注册的路由，根据路由的name进行删除
  router.getRoutes().forEach(route=>route.name && router.removeRoute(route.name))
  // 重新注册静态路由
  // staticRoutes.forEach(route => router.addRoute(route))
  addRoutes(staticRoutes)
}

/**
 * 用户信息
 * @methods setUserInfos 设置用户信息
 */
export const useUserInfoStore = defineStore('userInfo', {

	state: (): UserInfoState => ({
    token: getToken() as string,
    name: '',
    avatar: '',
    menuRoutes: [], //用于生成导航菜单的路由表
    buttons:[],
    roles:[]
  }),

	actions: {
    // 登录的异步action
   async login (username: string, password: string) {

    // 发送登录的请求
    const result = await loginApi(username,password)
    // 请求成功后，取出token保存 pinia和local中
    const token = result.token
    this.token = token
    setToken(token)
    },
   async getInfo () {

      // 请求获取用户信息
      const result = await getUserInfoApi()
      // 请求成功后，读取用户信息name和avatar，保存到state
      const {name,avatar,routes,buttons,roles} = result
      this.name = name
      this.avatar = avatar
      // 保存按钮权限列表和角色列表
      this.buttons = buttons
      this.roles = roles
      
       // 根据路由权限数据routes从allAsyncRoutes过滤出用户权限路由表, 进行动态注册
      const asyncRoutes = filterAsyncRoutes(cloneDeep(allAsyncRoutes) ,routes)
      asyncRoutes.forEach(route=>{
        router.addRoute(route)
      })
      router.addRoute(anyRouter) // 最后注册通配路由
      // 根据静态路由表+用户权限路由表合并生成权限导航菜单
      this.menuRoutes = [...staticRoutes, ...asyncRoutes]

      // 将静态路由表保存到state
      // this.menuRoutes = staticRoutes
    },

    async reset () {
      // 如果当前有用户名，请求退出登录接口
      if(this.name){
        // 加await后，下面的代码是在请求成功后执行的
        await logoutApi()
      }
      // 删除local中保存的token
      removeToken()
      // 提交重置用户信息的mutation
      this.token = ''
      this.name = ''
      this.avatar = ''
      this.menuRoutes = []
      this.buttons = []
      // 重新注册的路由 => 只注册静态路由，清除动态注册的路由
      resetRoute()
    },
	},
});
